/***********************************************************************************
Copy right:	    Coffee Tech.
Author:         jiaoyue
Date:           2021-11-25
Description:    上报处理几种方式
***********************************************************************************/

#include "report_handler.h"
#include "mqtt_handler.h"

/**
 * @brief 不上报，无需任何动作
 * 
 */
void report_none_handler()
{
    LOG_STD(APP_INFO, "excute report_none_handler");
    while (1)
    {
        sleep(100);
    }
}

/**
 * @brief 变化上报，需要不断对比缓存节点中的新旧数据，有变化再上报
 * 
 */
void report_change_handler()
{
    LOG_STD(APP_INFO, "excute report_change_handler");
    int node_count = *g_data.node_cache_p->total;
    struct std_node *node_p = g_data.node_cache_p->node_p; 

    while (1)
    {
        for (int i = 0; i < node_count; i++)
        {
            if(memcmp(&node_p[i].old_val, &node_p->new_val, sizeof(union val_t)))
            {
                //执行上报动作
                
                //上报成功后，需要将新值覆盖旧值
                node_p[i].old_val = node_p[i].new_val;  //联合体可以直接赋值
            }
        }
        usleep(100);  //可以稍微慢点轮询
    }
}

/**
 * @brief 周期上报，按照设定周期，定时轮询上报
 * 
 */
void report_period_handler()
{
    LOG_STD(APP_NOTICE, "excute report_period_handler");
    int node_count = *g_data.node_cache_p->total;
    struct std_node *node_p = g_data.node_cache_p->node_p; 
    int period = g_data.report_type_p->period;

    LOG_STD(APP_DEBUG, "node_count = %d", node_count);
    LOG_STD(APP_DEBUG, "period = %d", period);

    while (1)
    {
        char tmp_buf[64] = {0};
        cJSON *root = cJSON_CreateObject();
        cJSON_AddItemToObject(root, "type", cJSON_CreateNumber(1));
        cJSON_AddItemToObject(root, "result", cJSON_CreateNumber(0));

        cJSON *arr, *sub;
        arr = cJSON_CreateArray();   /*创建数组*/
        for (int i = 0; i < node_count; i++)
        {
            //组json包，上报所有点的值
            // LOG_STD(APP_DEBUG, "report key = %d", node_p[i].key);
            // LOG_STD(APP_DEBUG, "report val = %d", node_p[i].new_val);
            sub = cJSON_CreateObject();

            //增加key
            cJSON_AddNumberToObject(sub, "key", node_p[i].key);

            //增加val
            if(node_p[i].type == NODE_TYPE_BOOL)
            {
                if (node_p[i].new_val.b_val == TRUE)
                {
                    cJSON_AddStringToObject(sub, "val", "1");
                }
                else
                {
                    cJSON_AddStringToObject(sub, "val", "0");
                }
            }
            else if(node_p[i].type == NODE_TYPE_INT)
            {
                sprintf(tmp_buf, "%d", node_p[i].new_val.i_val);
                cJSON_AddStringToObject(sub, "val", tmp_buf);
            }
            else if(node_p[i].type == NODE_TYPE_FLOAT)
            {
                sprintf(tmp_buf, "%.2f", node_p[i].new_val.f_val);
                cJSON_AddStringToObject(sub, "val", tmp_buf);
            }
            else
            {
                LOG_STD(APP_ERR, "err type");
                continue;
            }

            cJSON_AddItemToArray(arr, sub);
        }

        //加入数组data
        cJSON_AddItemToObject(root, "data", arr);

        char *ptmp = cJSON_Print(root);
        mqtt_publish(TOPIC_DATA_UP, ptmp);

        LOG_STD(APP_DEBUG, "report str = %s", ptmp);

        free(ptmp);
        cJSON_Delete(root);

        sleep(period);
    }
}
